package com.neusoft.databus.core.controller;

import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.neusoft.bizcore.web.dto.result.PageResultDTO;
import com.neusoft.bizcore.web.dto.result.ResultDTO;
import com.neusoft.bizcore.web.dto.result.ResultListDTO;
import com.neusoft.bizcore.web.support.Searchable;
import com.neusoft.databus.common.dto.MetricDTO;
import com.neusoft.databus.core.service.MetricService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

/**
 * 指标管理控制器
 *
 * @author naxiang
 */
@Slf4j
@Api("指标管理控制器")
@RestController
@RequestMapping(value = "/api/w/metrics")
public class MetricController {
    @Autowired
    private MetricService metricService;

    /**
     * 查询所有指标
     *
     * @return
     */
    @ApiOperation("查询所有指标")

    @GetMapping
    public ResultListDTO<MetricDTO> index(final Searchable searchable) {
        final List<MetricDTO> DTOs = this.metricService.search(searchable);
        return ResultListDTO.success(DTOs);
    }

    /**
     * 分页查询所有指标
     *
     * @param searchable
     * @param pageable
     * @return
     */
    @ApiOperation("分页查询所有指标")
    @GetMapping("/p")
    public PageResultDTO<MetricDTO> search(final Searchable searchable, final Pageable pageable) {
        final Page<MetricDTO> DTOs = this.metricService.search(pageable, searchable);
        return PageResultDTO.success(DTOs);
    }

    @ApiOperation("查询单个指标")
    @GetMapping("/{code}")
    public ResultDTO<MetricDTO> searchByCode(@PathVariable final String code) {
        final MetricDTO dto = this.metricService.findByCode(code);
        return ResultDTO.success(dto);
    }

    @ApiOperation("查询单个指标")
    @GetMapping("/{code}/resource/{resourceCode}")
    public ResultDTO<MetricDTO> searchByResourceAndCode(@PathVariable final String resourceCode,
            @PathVariable final String code) {
        final MetricDTO dto = this.metricService.findByResourceAndCode(resourceCode, code);
        return ResultDTO.success(dto);
    }

    /**
     * 创建指标
     *
     * @param dto
     * @return
     */
    @ApiOperation("创建指标")
    @PostMapping
    public ResultDTO<MetricDTO> create(@RequestBody final MetricDTO dto) {
        final MetricDTO result = this.metricService.create(dto);
        return ResultDTO.success(result);
    }

    /**
     * 删除指标，物理删除
     *
     * @param id
     * @return
     */
    @ApiOperation("删除指标（內部使用）")
    @DeleteMapping("/{id}/deleteById")
    public ResultDTO<Void> deleteById(@PathVariable final Long id) {
        this.metricService.deleteById(id);
        return ResultDTO.success();
    }

    /**
     * 删除指标，物理删除
     *
     * @param code
     * @return
     */
    @ApiOperation("删除指标，物理删除")
    @DeleteMapping("/{code}")
    public ResultDTO<Void> deleteByCode(@PathVariable final String code) {
        this.metricService.deleteByCode(code);
        return ResultDTO.success();
    }

    @ApiOperation(value = "删除指标", hidden = true)
    @DeleteMapping("/batch")
    public ResultDTO<Void> deleteByIds(@RequestBody final List<Long> ids) {
        this.metricService.deleteByIdIn(ids);
        return ResultDTO.success();
    }

    /**
     * 修改指标
     *
     * @param code
     * @param dto
     * @return
     */
    @ApiOperation("修改指标")
    @PutMapping("/{code}")
    public ResultDTO<MetricDTO> update(@PathVariable final String code, @RequestBody final MetricDTO dto) {
        final MetricDTO result = this.metricService.update(code, dto);
        return ResultDTO.success(result);
    }

    /**
     * 指标导入
     *
     * @param file
     * @return
     */
    @ApiOperation("指标导入")
    @PostMapping("/import")
    public ResultDTO<Void> importTpl(@RequestParam("file") final MultipartFile file) {
        this.metricService.importTpl(file);
        return ResultDTO.success();
    }

    /**
     * 指标导出
     *
     * @param file
     * @return
     */
    @ApiOperation("指标导出")
    @GetMapping("/export")
    public void export(final Searchable searchable, final Pageable pageable, final HttpServletResponse response) {
        this.metricService.export(searchable, pageable, response);
    }

    @ApiOperation("下载指标导入模版")
    @GetMapping("/template")
    public void downloadTpl(final HttpServletResponse response) {

        final SXSSFWorkbook workbook = this.metricService.getTpl();
        OutputStream out = null;
        try {
            out = response.getOutputStream();
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-disposition",
                    String.format("attachment; filename=%s",
                            URLEncoder.encode(workbook.getSheetName(0) + ".xlsx", "UTF-8")));
            if (null != out) {
                workbook.write(out);
                out.flush();
            }
            out.close();
        } catch (final Exception e) {
            MetricController.log.error("下载指标导入模版异常：{}", e);
        } finally {
            try {
                out.close();
            } catch (final IOException e) {
                e.printStackTrace();
            }
        }
    }

}
